import {HttpClient} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {Storage} from '@ionic/storage';
import {API} from './api'
import 'rxjs/add/operator/toPromise';
import {ToastController} from 'ionic-angular';
import {Helper} from "./Helper";
import URLSearchParams from 'url-search-params';

@Injectable()
export class HttpProvider {

  constructor(public http: HttpClient,
              public toastCtrl: ToastController,
              public helper: Helper,
              public storage: Storage) {

  }

  ajax(options, success = (d) => {
  }, fail = (err) => {
  }) {
    return this.request({
      type: options.type,
      url: options.url,
      data: options.options.data
    }).then(d => {
      this.helper.stopLoading()
      options.options.complete && options.options.complete()
      options.options.success && options.options.success(d)
      success(d)
    }).catch(err => {
      this.helper.stopLoading()
      this.toastMsg(err.msg)
      options.options.complete && options.options.complete()
      options.options.fail && options.options.fail(err)
      fail(err)
    })
  }

  // toastErrMsg(err) {
  //   this.toastMsg(`系统错误：[${err.code}] ${err.msg}`)
  // }

  toastMsg(message: string) {
    let toast = this.toastCtrl.create({
      message: message,
      position: 'middle',
      duration: 3000
    })
    toast.present();
  }

  setTokenStorage(data) {
    return Promise.all([
      this.storage.set('token/accessToken', data.accessToken),
      this.storage.set('token/refreshToken', data.refreshToken),
      this.storage.set('token/type', data.type)
    ])
  }

  request(options) {
    options.data = options.data ? options.data : {}
    return this.storage.get('token/accessToken')
      .then(access_token => {
        let headers = Object.assign({
          'Authorization': "Bearer " + access_token,
          'Content-Type': 'application/x-www-form-urlencoded'
        }, options.headers ? options.headers : {})
        return this.http.request(options.type, options.url, {
          body: options.type == 'POST' ? this.makeURLSearchParams(options.data) : {},
          params: options.type == 'GET' ? options.data : {},
          headers: headers
        })
          .toPromise()
          .then(res => {
            let code = res['code']
            if (code == '0') {
              return res['data']
            } else {
              throw {
                code: code,
                msg: res['msg']
              }
            }
          })
      }).catch(err => {
        let code = err.code
        if (code == '60003') {
          //40001	access_token过期，需要使用refresh_token刷新accesss_token
          return this.refreshToken().then(() => {
            this.request(options)
          }).catch(err => {
            if (['60004', '60005'].indexOf(err.code) > -1) {
              //40002 refresh_token过期，需要重新登录
              /*************code 添加跳转登陆界面****************/
              this.helper.setStorage('user/login', '0')
              Helper.eventManage.emit('user/gotoLogin')
            } else {
              throw err
            }
          })
        } else {
          /*************code 添加错误处理（用户可看）****************/
          throw err
        }
      })
  }

  //调用该方法需自带 catch
  refreshToken() {
    return this.storage.get('token/refreshToken')
      .then(refresh_token => {
        return this.request({
          type: "POST",
          url: API.USER_REFRESH_TOKEN,
          data: {
            'refreshToken': refresh_token
          }
        }).then(d => {
          return this.setTokenStorage(d)
        }).catch(err => {

        })
      })
  }

  requestWithoutToken(options) {
    let headers = Object.assign({
      'Content-Type': 'application/x-www-form-urlencoded'
    }, options.headers)
    options.data = options.data ? options.data : {}
    return this.http.request(options.type, options.url, {
      body: options.type == 'POST' ? this.makeURLSearchParams(options.data) : {},
      params: options.type == 'GET' ? options.data : {},
      headers: headers
    }).toPromise().then(res => {
      let code = res['code']
      if (code == '0') {
        return res['data']
      } else {
        throw {
          code: code,
          msg: res['msg']
        }
      }
    })
  }

  makeURLSearchParams(obj) {
    let p = new URLSearchParams()
    for (let i in obj) {
      p.append(i, obj[i])
    }
    return p.toString()
  }

  clearTokenStorage() {
    this.storage.clear().then(() => {
      console.log('删除storage')
    })
  }
}

export interface AjaxOption {
  data?: any,
  complete?: any,
  success?: any,
  fail?: any,
  loading?: boolean,
}
